import { useGlobSetting } from '@/common/useSetting';
import { Ref, ref, unref } from 'vue';
import { useUserStoreWithOut } from '@/store/modules/user';
import moment from 'moment/moment';
import { Message, useNotifyStore } from '@/store/modules/notify';
const linAlive = uni.requireNativePlugin('Lin-Alive');

interface SocketReponse {
  /**
   * websocket的实例  可以自行覆盖对应回调函数 未开启websocket返回null
   */
  socketTask: UniApp.SocketTask | null;
  /**
   * 是否已经连接到websocket
   */
  websocketConnected: Ref<boolean>;
}

/**
 * 发送心跳包的间隔 ms
 */
const SEND_HEART_INTERVAL = 10000;
/**
 * 最大重连次数
 */
const RECONNECT_MAX_COUNT = 3;

/**
 * 微信小程序真机调试必须用wss协议  开发模式不需要
 * @param url websocketurl
 * @param sendHeartInterval 发送心跳包的间隔 ms
 * @param reconnectMaxCount 最大重连次数
 * @returns
 */
export function useWebsocket(
  url: string,
  sendHeartInterval = SEND_HEART_INTERVAL,
  reconnectMaxCount = RECONNECT_MAX_COUNT,
): { websocketConnected: Ref<boolean>; socketTask: Ref<UniApp.SocketTask> | null } {
  /**
   * 是否已经连接到websocket
   */
  const websocketConnected = ref<boolean>(false);
  /**
   * 是否正常关闭websocket
   */
  const websocketCloseNormal = ref<boolean>(true);
  /**
   * 发送心跳包定时器ID
   */
  const heartIntervalId = ref<any | null>(null);
  /**
   * 重连次数
   */
  const reconnectCount = ref<number>(0);

  const { enableWebsocket } = useGlobSetting();
  if (!enableWebsocket) {
    console.log('未开启websocket功能');
    return { socketTask: null, websocketConnected };
  }

  /**
   * 使用ref管理socketTask实例
   */
  const socketTask = ref<UniApp.SocketTask>(connectWebsocket());

  /**
   * 打开websocket连接
   * 如果希望返回一个 socketTask 对象，需要至少传入 success / fail / complete 参数中的一个。
   * @returns
   */
  function connectWebsocket(): UniApp.SocketTask {
    const task = uni.connectSocket({
      url,
      complete: () => {
        socketTask.value = task;
        bindEvent(socketTask, websocketConnected, reconnectCount, websocketCloseNormal);
      },
    });
    return task;
  }

  /**
   * 发送心跳包
   */
  function sendScoketHeart() {
    // heartIntervalId.value = setInterval(() => {
    if (unref(websocketConnected)) {
      socketTask.value.send({
        data: JSON.stringify({ type: 'ping' }),
      });
      // console.log('webscoket发送心跳包到服务器');
    } else if (!unref(websocketCloseNormal)) {
      // 重连 非正常关闭 报错才进行重连
      reconnectWebsocket();
    }
    // }, sendHeartInterval);
  }

  /**
   * 重连websocket
   */
  function reconnectWebsocket() {
    if (unref(reconnectCount) < reconnectMaxCount) {
      // 重置状态
      websocketConnected.value = false;
      websocketCloseNormal.value = true;

      // 延迟重连以避免立即重连失败
      setTimeout(() => {
        socketTask.value = connectWebsocket();
        reconnectCount.value += 1;
        console.log('正在重连websocket count:' + reconnectCount.value);
      }, 1000);
    } else {
      console.log('已超过最大websocket重连次数, 连接失败.');
      clearInterval(unref(heartIntervalId));
      // 重置计数器以便后续手动重连
      reconnectCount.value = 0;
    }
  }

  /**
   * 运行定时器
   */
  linAlive.stopAliveService((res: any) => {
    console.log('linAlive.stopAliveService', res);
  });
  linAlive.startAliveService(
    {
      title: '电梯服务',
      description: '持续获取电梯服务信息',
      hideFromTaskList: false,
      sendStatusWhenScreenOn: true,
      sendStatusScreenOnTime: 10,
      enableWakeLock: false,
      wakeLockScreenTime: 1,
    },
    (res: any) => {
      console.log('linAlive.startAliveService', res);
      sendScoketHeart();
    },
  );

  return { socketTask, websocketConnected };
}

function bindEvent(
  socketTask: Ref<{
    send: (options: UniApp.SendSocketMessageOptions) => void;
    close: (options: UniApp.CloseSocketOptions) => void;
    onOpen: (callback: (result: UniApp.OnSocketOpenCallbackResult) => void) => void;
    onClose: (callback: (result: any) => void) => void;
    onError: (callback: (result: UniApp.GeneralCallbackResult) => void) => void;
    onMessage: (callback: (result: UniApp.OnSocketMessageCallbackResult) => void) => void;
  }>,
  websocketConnected: Ref<boolean>,
  reconnectCount: Ref<number>,
  websocketCloseNormal: Ref<boolean>,
) {
  socketTask.value.onOpen((res) => {
    websocketConnected.value = true;
    reconnectCount.value = 0; // 重置重连计数器
    websocketCloseNormal.value = true; // 重置关闭状态
    console.log('websocket连接已经打开');
  });

  socketTask.value.onError((res) => {
    websocketConnected.value = false;
    websocketCloseNormal.value = false;
    console.log('websocket连接打开失败', res);
  });

  socketTask.value.onClose((res) => {
    websocketConnected.value = false;
    console.log('websocket连接已经关闭', res);
  });
  socketTask?.value.onMessage((response) => {
    let { data } = response;
    // 心跳包消息 不用管
    if (data === JSON.stringify({ type: 'ping' })) {
      return;
    }
    if (isJSON(data)) {
      let webSocketMessage = JSON.parse(data);
      console.log('收到消息:' + webSocketMessage);
      if (webSocketMessage.type === 'tiringEvent') {
        uni.createPushMessage({
          title: '电梯告警',
          content: '接收到电梯告警事件:' + webSocketMessage.data,
          payload: {
            elevatorId: webSocketMessage.elevatorId,
          },
          success: async (result) => {},
        });
      }
      data = webSocketMessage.data;
      // return;
    }
    const userStore = useUserStoreWithOut();
    // 其他消息
    const message: Message = {
      uid: userStore.userInfo?.userId || 0,
      date: moment(new Date()).format('YYYY-MM-DD HH:mm:ss'),
      content: data,
      read: false,
    };
    useNotifyStore().messageList.push(message);
  });
}

function isJSON(str: string) {
  try {
    JSON.parse(str);
    return true;
  } catch (e) {
    return false;
  }
}
